This notebook can be used to generate different Pareto-optimal data points for visualiation. The points generated in this notebook are computed from the subproblem decomposition weights used in Normal Boundary Intersection (NBI) method [1]. Currently this notebook implements following Pareto-optimal front (i.e. surface or point-clouds) through the generators module.
[1] I. Das and J. E. Dennis, "Normal-Boundary Intersection: A New Method for Generating the Pareto Surface in Nonlinear Multicriteria Optimization Problems," SIAM Journal on Optimization, vol. 8, (3), pp. 631-27, 1998. [pdf]
%matplotlib notebook
%reload_ext autoreload
%autoreload 2
import sys
import os
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from mpl_toolkits.mplot3d import Axes3D
sys.path.append('../src')
plt.rcParams.update({'figure.max_open_warning': 0})
from utils import transform as tr
from generators import dtlz2
dims = {"2d": 500, "3d": 1000, "4d": 2000, "8d": 4000}
for dim in dims:
# Open all files
fullpathf = "../data/dtlz2-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamex = filenamef.split('.')[0][0:-1] + 'x.csv'
fullpathx = os.path.join(path, filenamex)
print(path, filenamef, filenamex, frontname)
np.random.seed(123456)
r, n, m = 1, dims[dim], int(dim[0])
F, X = dtlz2.surface(r = r, n = n, m = m, mode = 'dd') # equidistant points
print("F.shape:", F.shape)
print("X.shape:", X.shape)
Ip = tr.pfindices(F)
F = F[Ip]
X = X[Ip]
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print(F[0:3,:])
print(X[0:3,:])
# Just to make sure if we can get correct F from X
F_ = np.zeros(F.shape)
for i in range(m):
if i < m-1:
F_[:,i] = np.prod(np.sin(X[:,0:i] * (np.pi / 2)), axis = 1) \
* np.cos(X[:,i] * (np.pi / 2))
else:
F_[:,i] = np.prod(np.sin(X[:,0:i-1] * (np.pi / 2)), axis = 1) \
* np.sin(X[:,i-1] * (np.pi / 2))
F_ = F_[:,::-1]
F_ = r * F_
# Plot
if dim == "2d":
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(F[:,0], F[:,1], s = 1)
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(X[:,0], lw = 1.0)
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(F_[:,0], F_[:,1], s = 1)
plt.show()
else:
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1, projection = '3d')
ax1.scatter(F[:,0], F[:,1], F[:,2], s = 1)
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(X[:,0], X[:,1], s = 1)
ax3 = fig.add_subplot(1, 3, 3, projection = '3d')
ax3.scatter(F_[:,0], F_[:,1], F_[:,2], s = 1)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathx, X, delimiter = ',', fmt = "%1.4e")
from generators import debmdk
dims = {"2d": 1000, "3d": 1500, "4d": 2500, "8d": 4100}
for dim in dims:
# Open all files
fullpathf = "../data/debmdk-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamex = filenamef.split('.')[0][0:-1] + 'x.csv'
fullpathx = os.path.join(path, filenamex)
print(path, filenamef, filenamex, frontname)
np.random.seed(123456)
r, n, m = 1, dims[dim], int(dim[0])
F, X = debmdk.surface(r = r, n = n, m = m, mode = 'dd') # uniform
print("F.shape:", F.shape)
print("X.shape:", X.shape)
Ip = tr.pfindices(F)
F = F[Ip]
X = X[Ip]
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print(F[0:3,:])
print(X[0:3,:])
# Just to make sure if we can get correct F from X
F_ = np.zeros(F.shape)
for i in range(m):
if i < m-1:
F_[:,i] = np.prod(np.sin(X[:,0:i] * (np.pi / 2)), axis = 1) \
* np.cos(X[:,i] * (np.pi / 2))
else:
F_[:,i] = np.prod(np.sin(X[:,0:i-1] * (np.pi / 2)), axis = 1) \
* np.sin(X[:,i-1] * (np.pi / 2))
F_ = F_[:,::-1]
F_ = r * F_
# Plot
if dim == "2d":
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(F[:,0], F[:,1], s = 1)
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(X[:,0], lw = 1.0)
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(F_[:,0], F_[:,1], s = 1)
plt.show()
else:
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1, projection = '3d')
ax1.scatter(F[:,0], F[:,1], F[:,2], s = 1)
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(X[:,0], X[:,1], s = 1)
ax3 = fig.add_subplot(1, 3, 3, projection = '3d')
ax3.scatter(F_[:,0], F_[:,1], F_[:,2], s = 1)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathx, X, delimiter = ',', fmt = "%1.4e")
from generators import debmdk
dims = {"2d": 500, "3d": 1000, "4d": 2000, "8d": 4000}
for dim in dims:
# Open all files
fullpathf = "../data/debmdk-all-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamex = filenamef.split('.')[0][0:-1] + 'x.csv'
fullpathx = os.path.join(path, filenamex)
print(path, filenamef, filenamex, frontname)
np.random.seed(123456)
r, n, m = 1, dims[dim], int(dim[0])
F, X = debmdk.surface(r = r, n = n, m = m, mode = 'dd') # uniform
print("F.shape:", F.shape)
print("X.shape:", X.shape)
# Ip = tr.pfindices(F)
# F = F[Ip]
# X = X[Ip]
# print("F.shape:", F.shape)
# print("X.shape:", X.shape)
print(F[0:3,:])
print(X[0:3,:])
# Just to make sure if we can get correct F from X
F_ = np.zeros(F.shape)
for i in range(m):
if i < m-1:
F_[:,i] = np.prod(np.sin(X[:,0:i] * (np.pi / 2)), axis = 1) \
* np.cos(X[:,i] * (np.pi / 2))
else:
F_[:,i] = np.prod(np.sin(X[:,0:i-1] * (np.pi / 2)), axis = 1) \
* np.sin(X[:,i-1] * (np.pi / 2))
F_ = F_[:,::-1]
F_ = r * F_
# Plot
if dim == "2d":
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(F[:,0], F[:,1], s = 1)
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(X[:,0], lw = 1.0)
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(F_[:,0], F_[:,1], s = 1)
plt.show()
else:
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1, projection = '3d')
ax1.scatter(F[:,0], F[:,1], F[:,2], s = 1)
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(X[:,0], X[:,1], s = 1)
ax3 = fig.add_subplot(1, 3, 3, projection = '3d')
ax3.scatter(F_[:,0], F_[:,1], F_[:,2], s = 1)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathx, X, delimiter = ',', fmt = "%1.4e")
from generators import cdebmdk
dims = {"2d": 7000, "3d": 18000, "4d": 80000, "8d": 3000000}
for dim in dims:
# Open all files
fullpathf = "../data/cdebmdk-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamex = filenamef.split('.')[0][0:-1] + 'x.csv'
fullpathx = os.path.join(path, filenamex)
filenamecv = filenamef.split('.')[0][0:-1] + 'cv.csv'
fullpathcv = os.path.join(path, filenamecv)
print(path, filenamef, filenamex, filenamecv, frontname)
np.random.seed(123456)
r, n, m = 1, dims[dim], int(dim[0])
F, X, CV = cdebmdk.surface(r = r, n = n, m = m, mode = 'dd') # uniform
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print("CV.shape:", CV.shape)
Ip = tr.pfindices(F)
F = F[Ip]
X = X[Ip]
CV = CV[Ip]
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print("CV.shape:", CV.shape)
print(F[0:3,:])
print(X[0:3,:])
print(CV[0:3])
# Just to make sure if we can get correct F from X. Here we
# don't apply the exact function as F, just map them on a sphere
# for the sanity check.
F_ = np.zeros(F.shape)
for i in range(m):
if i < m-1:
F_[:,i] = np.prod(np.sin(X[:,0:i] * (np.pi / 2)), axis = 1) \
* np.cos(X[:,i] * (np.pi / 2))
else:
F_[:,i] = np.prod(np.sin(X[:,0:i-1] * (np.pi / 2)), axis = 1) \
* np.sin(X[:,i-1] * (np.pi / 2))
F_ = F_[:,::-1]
F_ = r * F_
color = [cm.cool(v * 1.0) for v in CV]
# Plot
if dim == "2d":
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(F[:,0], F[:,1], s = 1, c = color)
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(X[:,0], lw = 1.0)
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(F_[:,0], F_[:,1], s = 1, c = color)
plt.show()
else:
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1, projection = '3d')
ax1.scatter(F[:,0], F[:,1], F[:,2], s = 1, c = color)
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(X[:,0], X[:,1], s = 1)
ax3 = fig.add_subplot(1, 3, 3, projection = '3d')
ax3.scatter(F_[:,0], F_[:,1], F_[:,2], s = 1, c = color)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathx, X, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathcv, CV, delimiter = ',', fmt = "%1.4e")
from generators import c0dtlz2
dims = {"2d": 750, "3d": 1300, "4d": 2500, "8d": 6000}
for dim in dims:
# Open all files
fullpathf = "../data/c0dtlz2-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamex = filenamef.split('.')[0][0:-1] + 'x.csv'
fullpathx = os.path.join(path, filenamex)
filenamecv = filenamef.split('.')[0][0:-1] + 'cv.csv'
fullpathcv = os.path.join(path, filenamecv)
print(path, filenamef, filenamex, filenamecv, frontname)
np.random.seed(123456)
r, n, m = 1, dims[dim], int(dim[0])
F, X, CV = c0dtlz2.surface(r = r, n = n, m = m, mode = 'dd') # non-uniform
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print("CV.shape:", CV.shape)
Ip = tr.pfindices(F)
F = F[Ip]
X = X[Ip]
CV = CV[Ip]
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print("CV.shape:", CV.shape)
print(F[0:3,:])
print(X[0:3,:])
print(CV[0:3])
# Just to make sure if we can get correct F from X.
F_ = np.zeros(F.shape)
for i in range(m):
F_[:,i] = np.prod(np.sin(X[:,0:m - (i + 1)] * (np.pi / 2)), axis = 1)
if i > 0:
F_[:,i] = F_[:,i] * np.cos(X[:,m - (i + 1)] * (np.pi / 2))
F_ = r * F_
color = [cm.cool(v * 1.0) for v in CV]
# Plot
if dim == "2d":
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(F[:,0], F[:,1], s = 1, c = color)
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(X[:,0], lw = 1.0)
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(F_[:,0], F_[:,1], s = 1, c = color)
plt.show()
else:
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1, projection = '3d')
ax1.scatter(F[:,0], F[:,1], F[:,2], s = 1, c = color)
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(X[:,0], X[:,1], s = 1)
ax3 = fig.add_subplot(1, 3, 3, projection = '3d')
ax3.scatter(F_[:,0], F_[:,1], F_[:,2], s = 1, c = color)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathx, X, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathcv, CV, delimiter = ',', fmt = "%1.4e")
from generators import c2dtlz2
dims = {"2d": 1000, "3d": 2500, "4d": 5000, "5d": 7500, "8d": 20000}
for dim in dims:
# Open all files
fullpathf = "../data/c2dtlz2-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamex = filenamef.split('.')[0][0:-1] + 'x.csv'
fullpathx = os.path.join(path, filenamex)
filenamecv = filenamef.split('.')[0][0:-1] + 'cv.csv'
fullpathcv = os.path.join(path, filenamecv)
print(path, filenamef, filenamex, filenamecv, frontname)
np.random.seed(123456)
r, n, m = 1, dims[dim], int(dim[0])
F, X, CV = c2dtlz2.surface(r = r, n = n, m = m, mode = 'dd') # uniform
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print("CV.shape:", CV.shape)
Ip = tr.pfindices(F)
F = F[Ip]
X = X[Ip]
CV = CV[Ip]
print("F.shape:", F.shape)
print("X.shape:", X.shape)
print("CV.shape:", CV.shape)
print(F[0:3,:])
print(X[0:3,:])
print(CV[0:3])
# Just to make sure if we can get correct F from X.
F_ = np.zeros(F.shape)
for i in range(m):
if i < m-1:
F_[:,i] = np.prod(np.sin(X[:,0:i] * (np.pi / 2)), axis = 1) \
* np.cos(X[:,i] * (np.pi / 2))
else:
F_[:,i] = np.prod(np.sin(X[:,0:i-1] * (np.pi / 2)), axis = 1) \
* np.sin(X[:,i-1] * (np.pi / 2))
F_ = F_[:,::-1]
F_ = r * F_
color = [cm.cool(v * 1.0) for v in CV]
# Plot
if dim == "2d":
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(F[:,0], F[:,1], s = 1, c = color)
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(X[:,0], lw = 1.0)
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(F_[:,0], F_[:,1], s = 1, c = color)
plt.show()
else:
fig = plt.figure(figsize = (9, 3))
ax1 = fig.add_subplot(1, 3, 1, projection = '3d')
ax1.scatter(F[:,0], F[:,1], F[:,2], s = 1, c = color)
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(X[:,0], X[:,1], s = 1)
ax3 = fig.add_subplot(1, 3, 3, projection = '3d')
ax3.scatter(F_[:,0], F_[:,1], F_[:,2], s = 1, c = color)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathx, X, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathcv, CV, delimiter = ',', fmt = "%1.4e")
from generators import dtlz8
# These factors need to be multiplied so that constraint violations
# are better visible when plotted with color.
cc = {2: 2.0, 3: 6.0, 4: 8.0, 6: 14.0, 8: 16.0}
dims = {'2d': [2, 50, 750], '3d': [3, 100, 11000], '4d': [4, 400, 80000], \
'6d': [6, 600, 320000], '8d': [8, 800, 160000]}
for dim in dims:
# Open all files
fullpathf = "../data/dtlz8-nbi/{0:s}/dataf.csv".format(dim)
path, filenamef = os.path.split(fullpathf)
dirs = path.split('/')
frontname = dirs[-2]
os.makedirs(path, exist_ok = True)
filenamecv = filenamef.split('.')[0][0:-1] + 'cv.csv'
fullpathcv = os.path.join(path, filenamecv)
print(path, filenamef, filenamecv, frontname)
np.random.seed(123456)
m, nl, ns = dims[dim][0], dims[dim][1], dims[dim][2]
F, _, _, CV = dtlz8.surface(m = m, nl = nl, ns = ns, mode = 'grid')
print("F.shape", F.shape)
print("CV.shape", CV.shape)
Ip = tr.pfindices(F)
F = F[Ip]
CV = CV[Ip]
print("F.shape:", F.shape)
print("CV.shape:", CV.shape)
print(F[0:3,:])
print(CV[0:3])
color = [cm.cool(v * cc[m]) for v in CV]
# Plot
if dim == "2d":
fig = plt.figure()
ax = fig.gca()
ax.scatter(F[:,0], F[:,1], s = 1, c = color)
plt.show()
else:
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(F[:,0], F[:,1], F[:,2], s = 1, c = color)
plt.show()
np.savetxt(fullpathf, F, delimiter = ',', fmt = "%1.4e")
np.savetxt(fullpathcv, CV, delimiter = ',', fmt = "%1.4e")